package com.etime.shycourse.services.ad.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.etime.shycourse.config.StatisticsMessage;
import com.etime.shycourse.dao.AdLogMapper;
import com.etime.shycourse.dto.AdLogDto;
import com.etime.shycourse.pojo.AdLog;
import com.etime.shycourse.pojo.Course;
import com.etime.shycourse.services.ad.interfaces.AdLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author why
 * @data 2022/7/18 21:32
 */
@Service
public class AdLogServiceImpl implements AdLogService {
    @Autowired
    private AdLogMapper adLogMapper;


    /**
     * 分页查询广告列表
     *
     * @param adLogDto 查询条件参数
     * @param pageNum  查询第几页
     * @param pageSize 每页查询多少数据
     * @return Page对象
     */
    @Override
    public Page<AdLogDto> selectAdLogPage(AdLogDto adLogDto, Long pageNum, Long pageSize) {
        Page<AdLogDto> page = new Page<>(pageNum, pageSize);
        QueryWrapper<AdLogDto> wrapper = new QueryWrapper<>();
        wrapper.eq(adLogDto.getAdstate() != null, "adstate", adLogDto.getAdstate());
        wrapper.gt(adLogDto.getAdstart() != null, "adend", adLogDto.getAdstart());
        wrapper.lt(adLogDto.getAdend() != null, "adstart", adLogDto.getAdend());
        wrapper.eq(adLogDto.getPlaceid() != null, "placeid", adLogDto.getPlaceid());
        wrapper.like(adLogDto.getCoursetitle()!=null&&!"".equalsIgnoreCase(adLogDto.getCoursetitle())
                ,"coursetitle",adLogDto.getCoursetitle());
        if (adLogDto.getField()==null||adLogDto.getWay()==null
                ||adLogDto.getField().equals("")||adLogDto.getWay().equals("")){
            wrapper.orderByDesc("adstart");
        }else {
            wrapper.orderBy(true,adLogDto.getWay().equalsIgnoreCase("asc")
                    ,adLogDto.getField());
        }
        return adLogMapper.selectAdLogPage(page, wrapper);
    }

    /**
     * 根据广告位限定的课程类型分页查询匹配的课程
     *
     * @param placeCourseTypeId 广告位限定课程类型id
     * @param pageNum           查询第几页
     * @param pageSize          每页查询多少数据
     * @param coursetitle       根据课程标题查找
     * @return 分页结果对象
     */
    @Override
    public Page<Course> selectCourseByPlaceCourseTypeId(Long placeCourseTypeId, String coursetitle, Long pageNum, Long pageSize) {
        Page<Course> page = new Page<>(pageNum, pageSize);
        Page<Course> coursePage = adLogMapper.selectCourseByPlaceCourseTypeId(page, placeCourseTypeId, coursetitle);
        return coursePage;
    }

    /**
     * 在每日凌晨1点时将开始时间小于当前时间的广告状态改为正常
     *
     * @return
     */
    @Scheduled(cron = "0 0 1 * * ?")
    public Integer timingUpdateAdLogPut() {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String strDate = sdf.format(date);
        return adLogMapper.updateAdLogPut(strDate);
    }

    /**
     * 在每日凌晨1点时将已到期的广告状态改为已下架
     *
     * @return
     */
    @Scheduled(cron = "0 0 1 * * ?")
    public Integer timingUpdateAdLogDown() {
        UpdateWrapper<AdLog> wrapper = new UpdateWrapper<>();
        long time = new Date().getTime();
        time = time - (1000 * 60 * 60 * 24);
        wrapper.lt("adend", new Date(time)).set("adstate", 3);
        return adLogMapper.update(null, wrapper);
    }

    /**
     * 根据广告位统计已投放和等待投放的广告在近一个月内的每天的个数<br/>
     * 步骤：<br/>
     * 1、根据广告位id获取已投放和等待投放数据列表<br/>
     * 2、遍历列表获取最小开始时间和最大结束时间<br/>
     * 3、获取当前日期，和最小开始时间做判断<br/>
     * （1）、如果最小日期比当前日期小则最小日期=当前日期<br/>
     * （2）、如果最小日期比当前日期大则最小日期不改变<br/>
     * 4、遍历最小日期到最大日期区间，每一天去列表中比较每一项的开始时间到结束时间中是否包含这一天<br/>
     * 如果包含count++，否则continue<br/>
     * 5、将每一天以及当天会投放的广告个数用map存放
     *
     * @param placeId
     * @return
     */
    @Override
    public List<StatisticsMessage> statisticsAdLogByPlaceId(Long placeId) {
        List<StatisticsMessage> List = new ArrayList<>();

        // 1、根据广告位id获取已投放和等待投放数据列表
        List<AdLog> adLogList = adLogMapper.statisticsAdLogByPlaceId(placeId);
        Date minTime = adLogList.get(0).getAdstart();//最大日期
        Date maxTime = adLogList.get(0).getAdend();//最小日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String strDate = sdf.format(new Date());
        Date nowTime = null;//当前日期
        try {
            nowTime = sdf.parse(strDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        // 2、遍历列表获取最小开始时间和最大结束时间
        for (AdLog adLog : adLogList) {
            if (adLog.getAdstart().compareTo(minTime) < 0) {
                minTime = adLog.getAdstart();
            }
            if (adLog.getAdend().compareTo(maxTime) > 0) {
                maxTime = adLog.getAdend();
            }
        }
        // 3、获取当前日期，和最小开始时间做判断
        if (minTime.compareTo(nowTime) < 0) {
            minTime = nowTime;
        }
        // 4、遍历最小日期到最大日期区间
        Long startTime = minTime.getTime();
        Long endTime = maxTime.getTime();
        Long oneDay = 24 * 3600 * 1000l;
        Integer count = 0;
        StatisticsMessage message = null;
        while (startTime <= endTime) {
            for (AdLog adLog : adLogList) {
                if (adLog.getAdstart().getTime() <= startTime &&
                        adLog.getAdend().getTime() >= startTime) {
                    count++;
                }
            }
            message = new StatisticsMessage();
            message.setStartDay(new Date(startTime));
            message.setEndDay(new Date(startTime + oneDay - 1000));
            startTime += oneDay;
            message.setCount(count);
            count = 0;

            List.add(message);
        }
        return List;
    }

    /**
     * 添加广告投放记录
     *
     * @param adLog
     * @return
     */
    @Override
    public Integer addAdLog(AdLog adLog) {
        return adLogMapper.insert(adLog);
    }

    /**
     * 根据广告id查询广告
     *
     * @param adid
     * @return
     */
    @Override
    public AdLog selectById(Long adid) {
        return adLogMapper.selectById(adid);
    }

    /**
     * 根据id修改广告记录
     *
     * @param adLog
     * @return
     */
    @Override
    public Integer updateAdLog(AdLog adLog) {
        return adLogMapper.updateById(adLog);
    }


}
